/**
 * My class for making happy living with console
 * Still in development
 * @author Pavel
 * @date 26/11/2012
 */
package educationTool.console;
import educationTool.control.*;
import educationTool.model.*;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;

/**
 * This is a Pavel class for managing visual interface of the program
 *
 * @author Pavel
 */
public class ConsoleManager implements View {
    private enum MenuType {

        MENU_FIRST_MENU, MENU_USER_MENU,
        MENU_ADMIN_MENU
    };
    private Core core = Core.getInstance();
    private ScheduleHandler schedule;
    private AdminController admin_logic = new AdminController();
    private boolean program_cycle = true;
    
    @Override
    public void showLessonsForToday(){
        List<Pair> today = core.getCurrentUser().getLessonList();
        for(Pair i : today) {
            System.out.println(i);
        }
    }

    /**
     *
     */
    @Override
    public void showLessonsForTomorrow() {
        LinkedList<Pair> pairs = schedule.getTomorrowLessons();
        if (pairs.isEmpty()) {
            System.out.println("Sorry, but today you got no pairs (yahoo!)");


        } else {
            System.out.println("Today lessons is:\n");

            for (Pair pair : pairs) {
                System.out.println(pair);
            }
        }
    }

    @Override
    public void showLessonsForCurrentWeek() {
        LinkedList<Pair> pairs = schedule.getCurrentWeekLessons();
        if (pairs.isEmpty()) {
            System.out.println("Sorry, but for this week you got no pairs (yahoo!)");


        } else {
            System.out.println("Current week lessons is:\n");

            for (Pair pair : pairs) {
                System.out.println(pair);
            }
        }
    }

    @Override
    public void showLessonsForNextWeek() {
        LinkedList<Pair> lessons = schedule.getNextWeekLessons();
        for(Pair i: lessons) {
            System.out.println(i);
        }
    }

    @Override
    public void showLessonsForPeriod(Date begin, Date end) {
        System.out.println("Lessons for period from"+
                begin.getDate()+" "+begin.getTime()+
                " to "+end.getDate()+" "+end.getTime()); 
                LinkedList<Pair> pairs = schedule.getLessonsForPeriod(begin, end);
                for( Pair i: pairs ) {
                    System.out.println(i);
                }
                    
    }
    
    private void logOut() {
        core.logOut();
        
    }

    private  void enterAdminMenu(Scanner sc) {
        showMenu(MenuType.MENU_ADMIN_MENU);
        boolean admin_menu_cycle = true;
        
        int user_action;
        
        while (admin_menu_cycle) {
            
            String user_input = sc.next();
            
            try {

            user_action = Integer.parseInt(user_input, 10);

            
            switch (user_action) {
                case 1: //Show users
                    ArrayList<User> users_list = core.getUsersList();
                    if (users_list.isEmpty()) {
                        System.out.println("No users now, sorry");
                    } else {
                        Set<User> user_ordered_set = new TreeSet<User>(users_list);
                        System.out.println();
                        for (User user : user_ordered_set) {
                            System.out.println(user);
                        }
                        System.out.println();
                    }
                    
                    break;
                case 2: //Add new user
                    System.out.println("Add new user\n"
                            + "Type in user login please:");
                    String user_login = sc.next();
                    System.out.println("Type in user password:");
                    String user_password = sc.next();
                    
                    if(admin_logic.createUser(user_login, user_password)) {
                        System.out.println("User creation ok");
                    } else {
                        System.out.println("Such user exists, sorry");
                    }
                    
                    break;
                case 3: //Delete user
                    System.out.println("Deleting existing user\n"
                            + "Type in user login please:");
                    user_login = sc.next();
                    if(admin_logic.deleteUser(user_login))
                        System.out.println("User has been succesfully deleted");
                    else
                        System.out.println("No user with such name, sorry!");
                    
                    break;
                case 4: //Log out as admin
                    core.logOut();
                    admin_menu_cycle = false;
                    //
                    break;
                case 5: //Exit admin menu and exit program
                    logOut();
                    admin_menu_cycle = false;
                    program_cycle = false;
                    //????
                    break;
                case 6: //Change admin password
                    changeAdminPass(sc, 3);
                    
                    break;
                case 7: //Change user password
                    editUserPass(sc);
                    
                    break;
                default:
                    System.out.println("Sorry, no such action, try again");
                    

                    break;




            }
            showMenu(MenuType.MENU_ADMIN_MENU);

        } catch (NumberFormatException ex) {
                System.out.println("Enter a number please");
                showMenu(MenuType.MENU_ADMIN_MENU);
                
            }
    }
        showMenu(MenuType.MENU_FIRST_MENU);
    }
    private void getPeriod(Scanner sc, Date begin_date, Date end_date) {
        boolean isWrongData = false;
        
        do {
            try {
                begin_date = new SimpleDateFormat("DD-MM-yyyy", Locale.ENGLISH).parse(sc.next());
            }
            catch (ParseException ex) {
                System.out.println("Input correct data");

                isWrongData = true;
            }

            isWrongData = false;

        } while (isWrongData);

        System.out.println("Input end date (DD-MM-yyyy):");
        
        do {
            try {
                end_date = new SimpleDateFormat("DD-MM-yyyy", Locale.ENGLISH).parse(sc.next());
            }
            catch (ParseException ex) {
                System.out.println("Input correct data");

                isWrongData = true;
            }
            isWrongData = false;

        } while (isWrongData);
    }
    private void enterUserMenu(Scanner sc) {
        schedule = new ScheduleHandler(core.getCurrentUser());
        showMenu(MenuType.MENU_USER_MENU);
        boolean cycle = true;
        while (cycle) {
            String input = sc.next();
            if(input.isEmpty()) {
                System.out.println("Please type a number");
                continue;
            }

            /* 
             * List of actions:
             *       1: Show timetable for the current day
             *       2: Show timetable for the next day
             *       3: Show timetable for the current week
             *       4: Show timetable for the next week
             *       5: Show timetable for time period
             *       6: Load TimeTable from <path>
             *       7: Log out
             *      
             */
            try {
                int choice = Integer.parseInt(input);
                switch (choice) {
                    case 1: //Show timetable for the current day
                        System.out.println("Show timetable for the current day");
                        showLessonsForToday();
                        
                        break;
                    case 2: //Show timetable for the next day
                        System.out.println("Show timetable for the next day");
                        showLessonsForTomorrow();
                        break;
                    
                    case 3: //Show timetable for the current week
                        System.out.println("Show timetable for current week");
                        showLessonsForCurrentWeek();
                        
                        break;
                    case 4: //Show timetable for the next week
                        System.out.println("Show timetable for the next week");
                        showLessonsForNextWeek();
                        break;
                    case 5: //Show timetable for period
                        System.out.println("Show timetable for period");
                        System.out.println("Input date from which to start, format DD-MM-yyyy :");
                        Date begin_date=null, end_date = null;
                        getPeriod(sc, begin_date, end_date);
                        showLessonsForPeriod(begin_date, end_date);
                        
                        break;
                    case 6: //Load timetable
                        System.out.println("Please type a path to a file, like:\n"
                                    + "C:\\Docs\\TimeTable.csv");
                        input = sc.next();
                        while(input.isEmpty()) {
                            System.out.println("Please type a path to a file, like:\n"
                                    + "C:\\Docs\\TimeTable.csv");
                        }
                        schedule.loadSchedule(input);
                        break;
                    case 7: //Log out
                        logOut();
                        cycle = false;
                        showMenu(MenuType.MENU_FIRST_MENU);
                        break;
                    
                    default:
                        System.out.println("No such action, please type a number from menu");
                        


                }
                showMenu(MenuType.MENU_USER_MENU);
            } catch (NumberFormatException ex) {
                System.out.println("Type a number please");
                
            }

        }
    }

  
    
    

    

    public  void showWelcomeMessage() {
        System.out.println("Welcome to the Education Tool Helper Program");
    }

    /**
     * Do a login for user
     *
     * @param sc A Scanner class object
     * @param number_of_trials How many times user can put a wrong password
     * @param isAdmin <b>True</b> if login as admin and <b>False</b> if want to
     * login as a user
     * 
     */
    public  void editUserPass(Scanner sc) {
        System.out.println("Editing user password\n"
                + "Type in user login please:");
        String user_login = sc.next();
        System.out.println("Type in user password:");
        String new_password = sc.next();
        admin_logic.changeUserPassword(user_login, new_password);
    }

    public  void changeAdminPass(Scanner sc, int trials) {
        System.out.println("Please type in your current password:");
        String old_password = sc.next();

        System.out.println("A new pasword:");
        String new_password = sc.next();

        while (!admin_logic.changeOwnPassword(old_password, new_password)) {
            System.out.println("Try again");
            trials--;
            if (trials == 0) {
                System.out.println("You've exceeded your limit for type in\n");
                //admin_menu_cycle = false;
                //ShowMenu(MenuType.MENU_FIRST_MENU);
                //admin_menu_cycle = false;
                break;
            }
            System.out.println("You have " + trials + " left");

            System.out.println("Type in an old password first:\n");
            old_password = sc.next();
            System.out.println("A new pasword:");
            new_password = sc.next();
        }
        if(trials!=0) {
            System.out.println("Password has been succesfully set");
        }
    }

    public boolean logIn(Scanner sc, int number_of_trials, final boolean isAdmin) {
        if (!isAdmin) {
            System.out.println("Type login:");
            while (number_of_trials > 0) {
                String login = sc.next();
                if (core.checkUserExistance(new User(login,""))) {
                    System.out.println("Type password:");
                    String password = sc.next();
                    return ( core.logInAsUser(login, password) ) ? true : false;

                } else {
                    number_of_trials--;
                    System.out.println("There's no user with such name, try again, login:\n"
                            + "Number of trilas left: " + number_of_trials);

                }

            }
        } else {
            while (number_of_trials > 0) {
                System.out.println("Type password:");
                String password = sc.next();
                if (!core.logInAsAdmin(password)) {
                    number_of_trials--;
                    System.out.println("You've entered a wrong password, again, password:\n"
                            + "Number of trilas left: " + number_of_trials);
                } else {
                    System.out.println("You've succesfully logged in!");
                    return true;
                }
            }
        }
        return false;

    }
    
    private  void showMenu(final MenuType mt) {
        switch (mt) {
            case MENU_FIRST_MENU:
                System.out.append("Please, choose the user type which you "
                        + "want to log in with\n");
                System.out.append("1: Admin\n");
                System.out.append("2: Regular user\n");
                System.out.append("3: Exit system\n");
                System.out.flush();
                break;
            case MENU_USER_MENU:
                System.out.append("Choose your action:\n"
                        + "1: Show timetable for the current day\n"
                        + "2: Show timetable for the next day\n"
                        + "3: Show timetable for the current week\n"
                        + "4: Show timetable for the next week\n"
                        + "5: Show timetable for time period\n"
                        + "6: Load TimeTable from <path>\n"
                        + "7: Log out\n"
                        );
              
                System.out.flush();
                break;
            case MENU_ADMIN_MENU:
                System.out.println(
                          "Choose your action:\n"
                        + "1: Show Users\n"
                        + "2: Add User\n"
                        + "3: Delete User\n"
                        + "4: Log out\n"
                        + "5: Exit\n"
                        + "6: Change your password\n"
                        + "7: Change user password\n"
                                 );

                System.out.flush();
                break;
        }

    }
    
    
    public void run() throws FileNotFoundException, IOException {
        Scanner scanner = new Scanner(System.in);
        //core.restoreUsers();
        showWelcomeMessage();
        showMenu(MenuType.MENU_FIRST_MENU); //Shows startup menu
        
        while (program_cycle) {
            String user_input = scanner.next();
            if (user_input.isEmpty()) {
                System.out.println("Please type a number");
                continue;
            }
            
            //Enter main cycle:
            
            int user_action;
            try {
            user_action = Integer.parseInt(user_input, 10);
            switch (user_action) {
                case 1: //LOGIN AS ADMIN
                    if(logIn(scanner, 3, true)) {
                        enterAdminMenu(scanner);
                    }
                    break;
                case 2: //Login as a regular user
                    if(logIn(scanner, 3, false)) {
                        enterUserMenu(scanner);
                    }
                        
                    break;
                case 3:
                   // core.storeUsers();
                    System.out.println("Bye!");
                    program_cycle = false;
                    break;
                default:
                    System.out.println("Sorry, no such action, try again");

            }
            } catch(NumberFormatException ex) {
                System.out.println("Please, type a number");
            }

        }
    }
  
        
    
    
}
